/**
 * 
 */
package org.ztest.thrift.serialize;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TMemoryBuffer;
import org.ztest.thrift.tutorial.Operation;
import org.ztest.thrift.tutorial.Work;

/**
 * 这个类演示基于thrift的序列化与反序列化
 * <p>
 * 数据写入protocol层，protocol层需要transport层承载数据，但是对象直接与protocol层打交道(read\write)
 * <p>
 * 所谓序列化、反序列化无非就是对象的转换与逆转换，直接点说就是将对象转换为byte[]和将byte[]转换为对象
 * 这么做是为了方便对象的存储和传输。
 * <p>
 * <b>注意：反序列化可以破坏单例模式</b>
 * @author lhl
 *
 * 2015年11月18日 下午6:40:38
 */
public class ThriftSerialize
{
	private static final int INITIAL_SIZE = 32;
	
	private Work mockObject()
	{
		Work work = new Work();
		work.num1 = 123;
		work.num2 = 456;
		work.op = Operation.ADD;
		work.comment = "加法，测试一下而已";
		return work;
	}
	
	public void serialize_compact() throws TException 
	{
		Work work = mockObject();
		
		// 序列化
		TMemoryBuffer mbuf = new TMemoryBuffer(INITIAL_SIZE);
		TProtocol prot = new TCompactProtocol(mbuf);
		work.write(prot);
		
		byte[] serializedBytes = mbuf.getArray();
		
		// 反序列化
		Work work2 = new Work();
		TMemoryBuffer mbuf2 = new TMemoryBuffer(INITIAL_SIZE);
		mbuf2.write(serializedBytes);
		TProtocol prot2 = new TCompactProtocol(mbuf2);
		work2.read(prot2);
		
		System.out.println("Compact size:" + serializedBytes.length);
		System.out.println("Before serialize:" + work);
		System.out.println("After deserialize:" + work2);
	}
	
	public void serialize_binary() throws TException 
	{
		Work work = mockObject();
		
		TMemoryBuffer mbuf = new TMemoryBuffer(INITIAL_SIZE);
		TProtocol prot = new TBinaryProtocol(mbuf);
		work.write(prot);
		
		byte[] serializedBytes = mbuf.getArray();
		Work work2 = new Work();
		TMemoryBuffer mbuf2 = new TMemoryBuffer(INITIAL_SIZE);
		mbuf2.write(serializedBytes);
		TProtocol prot2 = new TBinaryProtocol(mbuf2);
		work2.read(prot2);
		
		System.out.println("Binary size:" + serializedBytes.length);
		System.out.println("Before serialize:" + work);
		System.out.println("After deserialize:" + work2);
	}
	
	public void serialize_json() throws TException 
	{
		Work work = mockObject();
		
		TMemoryBuffer mbuf = new TMemoryBuffer(INITIAL_SIZE);
		TProtocol prot = new TJSONProtocol(mbuf);
		work.write(prot);
		
		byte[] serializedBytes = mbuf.getArray();
		Work work2 = new Work();
		TMemoryBuffer mbuf2 = new TMemoryBuffer(INITIAL_SIZE);
		mbuf2.write(serializedBytes);
		TProtocol prot2 = new TJSONProtocol(mbuf2);
		work2.read(prot2);
		
		System.out.println("JSON size:" + serializedBytes.length);
		System.out.println("Before serialize:" + work);
		System.out.println("After deserialize:" + work2);
	}
}
